package com.ruoyi.yanjing.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.yanjing.client.MqttPushClient;
import com.ruoyi.yanjing.common.DateUtil;
import com.ruoyi.yanjing.config.MqttConfig;
import com.ruoyi.yanjing.domain.DeviceTemperature;
import com.ruoyi.yanjing.domain.ElectricityPole;
import com.ruoyi.yanjing.domain.MonitorPoint;
import com.ruoyi.yanjing.domain.SendDataLog;
import com.ruoyi.yanjing.domain.mqtt.MqttSendData;
import com.ruoyi.yanjing.domain.req.PointMessageToTopicReq;
import com.ruoyi.yanjing.domain.req.QueryMessageByTopicReq;
import com.ruoyi.yanjing.service.IMonitorPointService;
import com.ruoyi.yanjing.service.ISendDataLogService;
import com.ruoyi.yanjing.service.MqttService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.stream.Collectors;

@Service
public class MqttServiceImpl implements MqttService {

    public static final Logger log = LoggerFactory.getLogger(MqttServiceImpl.class);


    @Autowired
    private MqttConfig mqttConfig;

    @Autowired
    private MqttPushClient mqttPushClient;

    @Resource
    ISendDataLogService sendDataLogService;

    @Resource
    IMonitorPointService iMonitorPointService;

    @Override
    public String addTopic(ElectricityPole electricityPole) {
        if(electricityPole != null && StringUtils.isNotBlank(electricityPole.getGatewayId())){
            String topic = "gateway/" + electricityPole.getGatewayId() + "/data";
            try {
                mqttConfig.addTopicSubscription(topic);
                log.info("动态订阅主题："+topic+"成功");
                return "SUCCESS";
            }catch (Exception e){
                log.info("动态订阅主题："+topic+"失败");
                return "FALSE";
            }

        }else{
            log.info("动态订阅主题失败");
            return "FALSE";
        }
    }

    @Override
    public String addTopic(String topic ) {
            try {
                mqttConfig.addTopicSubscription(topic);
                log.info("动态订阅主题："+topic+"成功");
                return "SUCCESS";
            }catch (Exception e){
                log.info("动态订阅主题："+topic+"失败");
                return "FALSE";
            }
    }


    /**
     * 添加温度告警配置
     * @param req
     * @return
     */
    @Override
    public String addMessageToTopic(PointMessageToTopicReq req) {
        SendDataLog sendDataLog = new SendDataLog();
        if(req == null){
            log.info("云端下发配置失败:参数不能为空");
            return "FALSE";
        }

        if(StringUtils.isBlank(req.getGatewayId())){
            log.info("云端下发配置失败:网关id不能为空");
            return "FALSE";
        }

        if(StringUtils.isBlank(req.getCmd())){
            log.info("云端下发配置失败:命令参数不能为空");
            return "FALSE";
        }

        String key = DictUtils.getDictLabel("temperature_limit","normal");
        req.setOverTempCfg(key);

        String topic = "gateway/"+req.getGatewayId()+"/configure";
        sendDataLog.setSendSystem("monitor");
        sendDataLog.setServerNo(topic);
        sendDataLog.setServerType("云端下发配置-发送");
        sendDataLog.setCreateTime(new Date());
        sendDataLog.setServerTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        sendDataLog.setSendTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        sendDataLog.setSendParamsType("tcp");

        MonitorPoint monitorPoint = new MonitorPoint();
        monitorPoint.setGatewayId(req.getGatewayId());
        List<MonitorPoint> monitorPoints = iMonitorPointService.selecAllMonitorPointAndLinePoleInfoList(monitorPoint);
        if(monitorPoints == null || monitorPoints.size() == 0){
            log.info("云端下发配置失败:当前网关下还未绑定传感器！");
            return "FALSE";
        }
        List<String> pointCodeList = monitorPoints.stream().map(MonitorPoint::getPointCode).collect(Collectors.toList());
        if(pointCodeList == null || pointCodeList.size() == 0){
            log.info("云端下发配置失败:当前网关下绑定的传感器未绑定物理设备！");
            return "FALSE";
        }
        req.setPointCode(pointCodeList);


        if(req.getPointCode() != null  && req.getPointCode().size() > 0){
            try {
                MqttSendData mqttSendData = new MqttSendData();
                mqttSendData.setCmd(req.getCmd());
                // 使用 ZonedDateTime 获取当前时间，并格式化为 ISO 8601 带 Z
                ZonedDateTime now = ZonedDateTime.now(TimeZone.getTimeZone("UTC").toZoneId());
                String formattedTime = now.format(DateTimeFormatter.ISO_INSTANT);
                mqttSendData.setTimestamp(formattedTime);
                List<MqttSendData.SensorData> sensorDataList = new ArrayList<>();
                for (String point : req.getPointCode()) {
                    MqttSendData.SensorData sensorData = new MqttSendData.SensorData();
                    sensorData.setSensor_id(point);
                    if(!"del_sensor".equals(req.getCmd())){
                        sensorData.setOver_temp_cfg(req.getOverTempCfg());
                    }
                    sensorDataList.add(sensorData);
                }
                mqttSendData.setSensors(sensorDataList);

                ObjectMapper objectMapper = new ObjectMapper();
                String pushMessage = objectMapper.writeValueAsString(mqttSendData);
                mqttPushClient.publish(0,true,topic,pushMessage);

                sendDataLog.setContent(pushMessage);
                sendDataLog.setSendStatus("发送成功");
                //订阅下发配置主题回复
                addTopic("gateway/"+req.getGatewayId()+"/configure_reply");
                log.info("下发网关回复配置消息到主题："+topic+"成功");
                log.info("下发网关回复配置内容："+pushMessage);
                sendDataLogService.insertSendDataLog(sendDataLog);


                log.info("下发配置到主题："+topic+"成功");
                return "SUCCESS";
            }catch (Exception e){
                log.info("下发配置到主题："+topic+"失败");
                sendDataLog.setSendStatus("发送失败：MQTT连接异常");
                sendDataLogService.insertSendDataLog(sendDataLog);
                return "FALSE";
            }

        }else{
            log.info("下发配置失败");
            sendDataLog.setSendStatus("发送失败：无网关信息");
            sendDataLogService.insertSendDataLog(sendDataLog);
            return "FALSE";
        }


    }

    /**
     * 查询温度告警配置
     * @param req
     * @return
     */
    @Override
    public String addQueryMessageToTopic(QueryMessageByTopicReq req) {
        SendDataLog sendDataLog = new SendDataLog();

        if(req == null){
            log.info("下发查询消息失败:参数不能为空！");
            return "FALSE";
        }

        if(StringUtils.isBlank(req.getCmd())){
            //默认查询所有
            req.setCmd("all");
        }

        String topic = "gateway/"+req.getGatewayId()+"/query";
        sendDataLog.setSendSystem("monitor");
        sendDataLog.setServerNo(topic);
        sendDataLog.setServerType("网关回复查询-发送");
        sendDataLog.setCreateTime(new Date());
        sendDataLog.setServerTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        sendDataLog.setSendTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        sendDataLog.setSendParamsType("tcp");


        if(StringUtils.isNotBlank(req.getGatewayId())){
            log.info("=================网关回复查询："+topic+"开始=================");
            try {

                // 使用 ZonedDateTime 获取当前时间，并格式化为 ISO 8601 带 Z
                ZonedDateTime now = ZonedDateTime.now(TimeZone.getTimeZone("UTC").toZoneId());

                String formattedTime = now.format(DateTimeFormatter.ISO_INSTANT);
                req.setTimestamp(formattedTime);


                ObjectMapper objectMapper = new ObjectMapper();
                String pushMessage = objectMapper.writeValueAsString(req);
                mqttPushClient.publish(0,true,topic,pushMessage);
                sendDataLog.setContent(pushMessage);
                sendDataLog.setSendStatus("发送成功");
                //订阅查询主题回复
                addTopic("gateway/"+req.getGatewayId()+"/query_reply");
                log.info("下发网关回复查询消息到主题："+topic+"成功");
                log.info("下发网关回复查询内容："+pushMessage);
                sendDataLogService.insertSendDataLog(sendDataLog);
                return "SUCCESS";
            }catch (Exception e){
                log.info("下发网关回复查询消息到主题："+topic+"失败");
                sendDataLog.setSendStatus("发送失败：MQTT连接异常");
                sendDataLogService.insertSendDataLog(sendDataLog);
                return "FALSE";
            }

        }else{
            log.info("下发网关回复查询消息失败");
            sendDataLog.setSendStatus("发送失败：无网关信息");
            sendDataLogService.insertSendDataLog(sendDataLog);
            return "FALSE";
        }


    }
}
